<template>
    <div class="QilinTable">
        <el-table
            ref="tableRef"
            :data="ownTableConfig.tableData"
            :border="ownTableConfig.elTableConfig?.border"
            :stripe="ownTableConfig.elTableConfig?.stripe || false"
            :size="ownTableConfig.elTableConfig?.size || 'default'"
            :row-key="ownTableConfig.elTableConfig?.rowKey || 'id'"
            :default-expand-all="ownTableConfig.elTableConfig?.defaultExpandAll || false"
            :highlight-current-row="ownTableConfig.elTableConfig?.highlightCurrentRow"
            :span-method="ownTableConfig.elTableConfig?.spanMethod"
            :cell-style="ownTableConfig.elTableConfig?.cellStyle"
            :height="ownTableConfig.elTableConfig?.height || '100%'"
            @select="selectRowData"
            @select-all="selectAllRowData"
            @selection-change="selectionChangeData"
            @row-click="rowClickData"
            @expand-change="expandChangeData"
            @current-change="currentChangeData"
            @sort-change="sortChangeData"
        >   
            <template
                v-for="(item,index) in ownTableConfig.headerConfig"
                :key=" item.label+index || 'column-item-'+index "
            >
                <TableColumn :item="item">
                    <template v-if="item.type === 'slot' " v-slot:[item.slotName]="slotData">
                        <slot :name="item.slotName" :data="{scope:slotData.data.scope,item}"></slot>
                    </template>
                    <template v-else-if="item.type === 'customOperate' " v-slot:elTableColumn>
                        <slot name="elTableColumn" :data="{item}"></slot>
                    </template>
                    <template v-else-if="item.headerSlot" v-slot:elTableHeader>
                        <slot name="elTableHeader" :data="{item}"></slot>
                    </template>
                </TableColumn>
            </template>
            <template v-slot:empty>
                <div class="qilin-table-empty">
                    <img src="@/assets/images/dataEmpty.svg" alt="">
                    <p>暂无内容~</p>
                </div>
            </template>
        </el-table>
        <el-pagination
            v-if="!ownTableConfig.paginationsObj?.isHide"
            :current-page="ownTableConfig.paginationsObj?.currentPage"
            :page-sizes="ownTableConfig.paginationsObj?.pageSizes"
            :page-size="ownTableConfig.paginationsObj?.pageSize"
            :total="ownTableConfig.paginationsObj?.total"
            :layout="ownTableConfig.paginationsObj?.layout"
            @current-change="handleCurrentPage"
            @size-change="handleSizeChange"
            background
        ></el-pagination>
    </div>
</template>

<script setup>
import {defineOptions,ref,reactive,computed,nextTick} from "vue";
import Qilin from "qilin-utils";

defineOptions({
    name:"QilinTable"
});

/*
    数据变量定义区域
*/
// 获取表格元素DOM
const tableRef = ref(null);
let currentRow = {};// 当前行数据
let curretnExpandRowId = null; //当前行数据id唯一标识


/*
    计算属性等代码区域
*/
// 接收来自父组件的传值
const propsValue = defineProps({
    tableConfig: {
        type: Object,
        default() {
            return {
                // el-table标签上的配置项
                elTableConfig: {
                    border: true, //是否带边框--默认true
                    stripe: false, //是否为斑马纹--默认false
                    size: "default", //表格大小--默认default
                    rowKey: "id",
                    defaultExpandAll:false, //	是否默认展开所有行，当 Table 包含展开行存在或者为树形表格时有效，默认false
                    highlightCurrentRow: false, //是否高亮当前行
                    spanMethod:"event", //合并行或列的方法
                    cellStyle:"event|object", //单元格的style的回调方法，也可以使用一个固定的object为所有单元格设置一样的style
                    height:"100%", //table的高度，默认100%
                },
                // 表头相关配置项
                headerConfig: [
                    {
                        label: "姓名", //表头名称
                        prop: "name", //对应后台数据名称
                        type: "text", //表头的类型--默认为text
                        slotName: "", //slot元素的name，当且仅当type为slot时有效
                        fixed: "right", //是否固定--当且仅当type为operate时生效--默认right
                        format: "", //时间格式化配置
                        align: "center", //对齐方式--默认center
                        width: 60, //列宽-自适应宽度
                        minWidth: 60, //列宽-对应列的最小宽度
                        ellipsis: false, //是否超出悬浮展示--默认false
                        tooltipOptions:{ //超出悬浮配置项
                            content:"我是你爹",
                            placement:"top"
                        },
                        replaceValue: "-", //若值为空，则默认显示为-
                        headerSlot:false, //是否开启自定义表头插槽，默认false
                        isHide: false, //是否隐藏某个表头，默认false
                        isHideFn:"event", //是否隐藏某个表头的方法
                        isShowExpandTooltip: false, //是否开启展开行功能
                        expandTooltipFn: "event", //展开行内容方法，内容由方法返回
                        hideSeparate: false, //操作按钮之间是否具有分隔符-默认false，有
                        operateOptions: [ //操作栏按钮配置项--当且仅当type为operate生效
                            {
                                btnName: "按钮", //按钮名称--旧版本buttonName
                                btnType: "default", //按钮类型--默认default--旧版本buttonType
                                btnSize: "small", //按钮大小--默认mini--旧版本buttonSize
                                btnClick: "event", //按钮点击事件--旧版本buttonEvent
                                isHide: false, //是否隐藏该按钮
                                disabled: false, //是否禁用
                                isDisabled: "event", //判断当前按钮是否禁用的方法
                                isHideFn: "event", //判断当前按钮是否隐藏的方法
                                iconfontClass:"iconfont", //当使用自定义图标时的class类
                            }
                        ],
                        moreOperateOptions: [ //操作栏更多按钮配置项--当且仅当type为operate生效
                            {
                                btnName: "按钮", //按钮名称--旧版本buttonName
                                btnType: "default", //按钮类型--默认default--旧版本buttonType
                                btnSize: "small", //按钮大小--默认mini--旧版本buttonSize
                                btnClick: "event", //按钮点击事件--旧版本buttonEvent
                                isHide: false, //是否隐藏该按钮
                                disabled: false, //是否禁用
                                isDisabled: "event", //判断当前按钮是否禁用的方法
                                isHideFn: "event", //判断当前按钮是否隐藏的方法
                                iconfontClass:"iconfont", //当使用自定义图标时的class类
                            }
                        ]
                    }
                ],
                // 真实数据
                tableData: [],
                // 表格分页配置项
                paginationsObj: {
                    isHide: false, //是否隐藏分页器
                    currentPage: 1, //当前页
                    pageSize: 10, //当前每页数量
                    pageSizes: [10, 20, 30], //每页显示多少条选项集
                    total: 0, //表格总数量
                    layout: "total,sizes,prev,pager,next,jumper"
                }
            };
        }
    }
});

// 暴露父组件自定义方法
const emits = defineEmits(
    [
        "update:tableConfig",
        "changeCurrentPage",
        "changeCurrentSize",
        "selectRowData",
        "selectAllRowData",
        "selectionChangeData",
        "rowClickData",
        "expandChangeData",
        "currentChangeData",
        "sortChangeData"
    ]
);

// 组件自身的配置项
const ownTableConfig = computed({
    get() {
        return propsValue.tableConfig;
    },
    set(val) {
        emits("update:tableConfig", val);
    }
});


/*
    逻辑脚本代码区域
*/
// 监听表格行展开收缩事件监听
const expandChangeData = (row, expandedRows) => {
    // 正常以下这行代码不应写在这里，为方便统一修改，暂时如此写着......
    currentRow = row;
    curretnExpandRowId = row.id;
    if (expandedRows.length > 1) {
        tableRef.value.toggleRowExpansion(expandedRows[0]);
    } else {
        if (expandedRows.length === 1) {
            curretnExpandRowId = expandedRows[0].id;
        } else {
            curretnExpandRowId = null;
        };
    };
    emits("expandChangeData", row, expandedRows, curretnExpandRowId);
};

// 监听切换页面事件
const handleCurrentPage = (page) => {
    emits("changeCurrentPage", page);
};
// 监听切换每页数量
const handleSizeChange = (size) => {
    emits("changeCurrentSize", size);
};
// 监听选择表格某行数据事件
const selectRowData = (selection, row) => {
    emits("selectRowData", selection, row);
};
// 监听选择表格全选数据事件
const selectAllRowData = (selection) => {
    emits("selectAllRowData", selection);
};
//监听选择表格事件
const selectionChangeData = (selection) => {
    emits("selectionChangeData", selection);
}
// 监听表格行单击事件
const rowClickData = (row, column, event) => {
    emits("rowClickData", row, column, event);
};
// 监听表格的当前行发生变化的事件--需配合属性highlight-current-row一起使用
const currentChangeData=(currentRow,oldCurrentRow)=>{
    emits("currentChangeData",currentRow,oldCurrentRow);
};
// 监听当表格排序条件发生变化时触发事件
const sortChangeData=(data)=>{
    emits("sortChangeData",data);
};

// 调用el-table的setCurrentRow事件监听--用于单选表格，设定某一行为选中行， 如果调用时不加参数，则会取消目前高亮行的选中状态。
const setCurrentRow = (row) => {
    tableRef.value.setCurrentRow(row);
}
// 调用el-table的toggleRowExpansion事件监听--切换行的展开与收缩
const toggleRowExpansion = (row, flag) => {
    tableRef.value.toggleRowExpansion(row, flag);
};
// 调用el-table的clearSelection事件监听--清空用户的选择
const clearSelection = () => {
    tableRef.value.clearSelection();
};
// 调用el-table的toggleRowSelection事件监听--用于多选表格，切换某一行的选中状态
const toggleRowSelection=(row, selected)=>{
    tableRef.value.toggleRowSelection(row, selected);
};
// 调用el-table的toggleAllSelection事件监听--用于多选表格，切换全选全不选的选中状态
const toggleAllSelection=()=>{
    tableRef.value.toggleAllSelection();
};
// 调用el-table的sort事件监听--用于手动排序表格
const sort=(prop,order)=>{
    tableRef.value.sort(prop,order);
};


/*
    生命周期等代码区域
*/
defineExpose({
    toggleRowExpansion,
    clearSelection,
    toggleRowSelection,
    setCurrentRow,
    toggleAllSelection,
    sort
});

</script>

<style lang="scss" scoped>
.QilinTable{
    width: 100%;
    display: flex;
    flex-flow: column nowrap;
    flex: 1;
    min-height:0;
    :deep(>.el-table) {
        flex: 1;
        th.el-table__cell{
            background-color:#F5F7FA;
            font-weight:700;
            padding:12px 0;
            &:hover{
                cursor:default;
            }
        }
        .cell{
            >.slot-box{
                height:100%;
            }
            &.el-tooltip{
                >.slot-box{
                    height:100%;
                    overflow:hidden;
                    white-space:nowrap;
                    text-overflow:ellipsis;
                    >div{
                        overflow:hidden;
                        white-space:nowrap;
                        text-overflow:ellipsis;
                    }
                }
            }
            .el-button{
                padding:8px 10px;
                &+.el-button{
                    margin-left:8px;
                }
            }
            .el-dropdown {
                color: #409eff;
                padding: 9px 12px;
                >span {
                    display: flex;
                    align-items: center;
                    outline: 0;
                    cursor: pointer;
                }
            }
        }
        .operate-box {
            >.el-button:not(:first-child) {
                position: relative;
                &::before {
                    position: absolute;
                    top: 50%;
                    left: -8%;
                    transform: translateY(-50%);
                    content: "";
                    width: 1px;
                    height: 60%;
                    background-color: $border-color;
                }
            }
            .el-dropdown {
                color: #409eff;
                padding: 9px 12px;
                >span {
                    display: flex;
                    align-items: center;
                    outline: 0;
                    cursor: pointer;
                }
                &::before {
                    position: absolute;
                    top: 50%;
                    left: -10%;
                    transform: translateY(-50%);
                    content: "";
                    width: 1px;
                    height: 60%;
                    background-color: $border-color;
                    margin-left: 8px;
                }
            }
        }
        .el-table__empty-block{
            min-height:180px !important;
        }
        .qilin-table-empty {
            line-height: 24px;
        }
        .el-table__placeholder{
            display:none;
        }
        .el-table__expand-column{
            border-right: 0 solid transparent;
            >div.cell {
                display: none;
            }
        }
        .el-table__expanded-cell{
            background-color: rgba(0, 0, 0, 0.02);
            padding: 15px 50px;
        }
    }
    >.el-pagination {
        justify-content: flex-end;
        padding-top:16px;
    }
}
</style>
